package com.yk.common.core.domain;

import cn.hutool.core.collection.CollUtil;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;

/**
 * 响应信息主体
 *
 * @author lmx
 * @date 2023/10/13 13:48
 */
@Data
@NoArgsConstructor
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 成功
     */
    public static final int SUCCESS = 200;

    /**
     * 失败
     */
    public static final int FAIL = 500;

    /**
     * 消息状态码
     */
    private int code;

    /**
     * 消息内容
     */
    private String msg;

    /**
     * 日志操作内容
     */
    private String logMsg;

    /**
     * 数据对象
     */
    private T data;

    public static <T> Result<T> ok() {
        return restResult(null, SUCCESS, "操作成功", null);
    }

    public static <T> Result<T> ok(T data) {
        return restResult(data, SUCCESS, "操作成功", null);
    }

    public static <T> Result<T> ok(String msg) {
        return restResult(null, SUCCESS, msg, null);
    }

    public static <T> Result<T> ok2Log(String logMsg) {
        return restResult(null, SUCCESS, null, logMsg);
    }

    public static <T> Result<T> ok(String msg, T data) {
        return restResult(data, SUCCESS, msg, null);
    }

    public static <T> Result<T> data(T data) {
        return restResult(data, SUCCESS, "操作成功", null);
    }

    public static <T> Result<T> data2Log(T data, String logMsg) {
        return restResult(data, SUCCESS, "操作成功", logMsg);
    }

    public static <T> Result<T> fail() {
        return restResult(null, FAIL, "操作失败", null);
    }

    public static <T> Result<T> fail(String msg) {
        return restResult(null, FAIL, msg, null);
    }

    public static <T> Result<T> fail2Log(String msg, String logMsg) {
        return restResult(null, FAIL, msg, logMsg);
    }

    public static <T> Result<T> fail2Log(int code, String msg, String logMsg) {
        return restResult(null, code, msg, logMsg);
    }

    public static <T> Result<T> fail(T data) {
        return restResult(data, FAIL, "操作失败", null);
    }

    public static <T> Result<T> fail(String msg, T data) {
        return restResult(data, FAIL, msg, null);
    }

    public static <T> Result<T> fail(int code, String msg) {
        return restResult(null, code, msg, null);
    }

    private static <T> Result<T> restResult(T data, int code, String msg, String logMsg) {
        Result<T> r = new Result<T>();
        r.setCode(code);
        r.setData(data);
        r.setMsg(msg);
        r.setLogMsg(logMsg);
        return r;
    }

    public Boolean isSuccess() {
        return SUCCESS == this.code;
    }

    public static <T> Boolean isError(Result<T> ret) {
        return !isSuccess(ret);
    }

    public static <T> Boolean isSuccess(Result<T> ret) {
        return Result.SUCCESS == ret.getCode();
    }

    public static <T> Boolean isNull(Result<T> ret) {
        return Objects.isNull(ret.getData());
    }

    public static <T> Boolean isCollNull(Result<T> ret) {
        return CollUtil.isEmpty((Collection<?>) ret.getData());
    }
}
